package com.trans.auxiliary;


import com.trans.anno.Info;
import com.trans.enums.Origin;
import lombok.extern.slf4j.Slf4j;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Objects;

/**
 * 字段属性对象
 * @Author xwduo
 * @Date 2023-05-30 17:52
 */
@Slf4j
public class Params {

    @Info("字段来源")
    private final Origin origin;

    @Info("属性-成员变量")
    private final Field field;

    @Info("属性-IS或GET 方法")
    private final Method method;

    @Info("属性- Java language modifiers ")
    public final int modifier;

    @Info("属性- 类型")
    public final Class type;

    @Info("属性- 名称")
    public final String name;

    @Info("属性- 原始值")
    public Object value;

    public Params( Method method ,  String realName) {
        this.origin = Origin.METHOD;
        this.field = null;
        this.method = method;
        this.modifier = method.getModifiers();
        this.type = method.getReturnType();
        this.name = realName;
    }

    public Params( Method method ,Field field,  String realName) {
        this.origin = Origin.METHOD;
        this.field = field;
        this.method = method;
        this.modifier = method.getModifiers();
        this.type = method.getReturnType();
        this.name = realName;
    }

    public Params(Field field) {
        this.origin = Origin.FIELD;
        this.field = field;
        this.method = null;
        this.modifier = field.getModifiers();
        this.type = field.getType();
        this.name = field.getName();
        this.value = null;
    }

    public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
        Objects.requireNonNull(annotationClass);
        switch (origin){
            case METHOD:
                T annotation = method.getAnnotation(annotationClass);
                if(null == annotation && null != field){
                    return field.getAnnotation(annotationClass);
                }
                return annotation;
            case FIELD:return field.getAnnotation(annotationClass);
            default: return null;
        }
    }

    public Params setValue(Object value) {
        this.value = value;
        return this;
    }

    public Params setValue(Object obj, Object fieldValue) {
        if(field != null){
            boolean accessible = field.isAccessible();
            field.setAccessible(true);
            try {
                field.set(obj,fieldValue);
                field.setAccessible(accessible);
            }catch (Exception e){
                log.info("无法设置对象值");
            }
        }
        return this;
    }

    public Object findObjectVal(Object obj){
        boolean accessible;
        Object o;
        try {
            switch (origin){
                case METHOD:
                    accessible = method.isAccessible();
                    method.setAccessible(true);
                    o = method.invoke(obj);
                    method.setAccessible(accessible);
                    return o;
                case FIELD:
                    accessible = field.isAccessible();
                    field.setAccessible(true);
                    o = field.get(obj);
                    field.setAccessible(accessible);
                    return o;
                default: return null;
            }
        }catch (Exception e){
            log.info("无法获取对象值");
            return null;
        }
    }
}
